package site.ruolin;


import site.ruolin.Decrypt.Decrypt;
import site.ruolin.Encrypt.Encrypt;
import site.ruolin.KeyGen.Key.KeyPair;
import site.ruolin.KeyGen.KeyGen;
import site.ruolin.Operator.Operator;

import java.math.BigInteger;
import java.util.Scanner;

public class Main {
    private static final int KEY_SIZE = 512; // 素数（p、q）的位数

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);

        System.out.println("------ Paillier同态加密算法演示 ------");

        // 生成密钥对
        System.out.println("\n1. 正在生成密钥对...");
        KeyGen keyGen = new KeyGen(KEY_SIZE);
        KeyPair keyPair = keyGen.generateKeyPair();

        System.out.println("密钥生成完成！");
        System.out.println("公钥 n = " + keyPair.getPublicKey().getN());
        System.out.println("公钥 g = " + keyPair.getPublicKey().getG());

        // 创建加密器、解密器和同态运算器
        Encrypt encrypt = new Encrypt(keyPair.getPublicKey());
        Decrypt decrypt = new Decrypt(
                keyPair.getPrivateKey(), keyPair.getPublicKey());
        Operator operator = new Operator(keyPair.getPublicKey());

        // 加密演示
        System.out.println("\n2. 加密演示");
        System.out.print("请输入第一个明文数字 m1: ");
        BigInteger m1 = scanner.nextBigInteger();
        System.out.print("请输入第二个明文数字 m2: ");
        BigInteger m2 = scanner.nextBigInteger();

        BigInteger c1 = encrypt.encrypt(m1);
        BigInteger c2 = encrypt.encrypt(m2);

        System.out.println("明文 m1 = " + m1);
        System.out.println("密文 c1 = " + c1);
        System.out.println("明文 m2 = " + m2);
        System.out.println("密文 c2 = " + c2);

        // 解密演示
        System.out.println("\n3. 解密演示");
        BigInteger decrypted_m1 = decrypt.decrypt(c1);
        BigInteger decrypted_m2 = decrypt.decrypt(c2);

        System.out.println("解密得到 m1 = " + decrypted_m1);
        System.out.println("解密得到 m2 = " + decrypted_m2);

        // 同态加法演示
        System.out.println("\n4. 同态加法演示");
        System.out.println("直接计算明文加法: " + m1 + " + " + m2 + " = " + m1.add(m2));

        BigInteger c_add = operator.add(c1, c2);
        BigInteger decrypted_add = decrypt.decrypt(c_add);
        System.out.println("密文相加后解密: " + decrypted_add);

        // 同态数乘演示
        System.out.println("\n5. 同态数乘演示");
        System.out.print("请输入一个常数 k: ");
        BigInteger k = scanner.nextBigInteger();
        System.out.println("直接计算明文数乘: " + m1 + " * " + k + " = " + m1.multiply(k));

        BigInteger c_mult = operator.multiply(c1, k);
        BigInteger decrypted_mult = decrypt.decrypt(c_mult);
        System.out.println("密文数乘后解密: " + decrypted_mult);

        scanner.close();
    }
}